package ext.generic.project.reports;

import java.io.IOException;
import java.math.BigDecimal;
import java.rmi.RemoteException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import wt.doc.WTDocument;
import wt.epm.EPMDocument;
import wt.fc.ObjectReference;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.collections.WTCollection;
import wt.method.RemoteMethodServer;
import wt.org.OrganizationServicesHelper;
import wt.org.WTUser;
import wt.part.WTPart;
import wt.projmgmt.admin.Project2;
import wt.query.QueryException;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.util.WTException;
import wt.util.WTProperties;
import wt.util.WTStandardDateFormat;

import com.ptc.projectmanagement.deliverable.PlanDeliverable;
import com.ptc.projectmanagement.deliverable.PlanDeliverableLink;
import com.ptc.projectmanagement.plan.PlanActivity;
import com.ptc.projectmanagement.plan.Plannable;
import com.ptc.projectmanagement.plannable.PlannableHelper;
import com.ptc.projectmanagement.util.NumberFormattingUtils;

import ext.generic.project.reports.bean.PhaseReviewDocBean;

/**
 * 项目报表工具类
 * 
 * @author John
 * 
 */
public class ProjectReportUtil {
	private static boolean VERBOSE;
	private static String CLASSNAME = ProjectReportUtil.class.getName();
	private static String codebalocation;
	private static WTProperties wtProperties = null;

	static {
		try {
			wtProperties = WTProperties.getLocalProperties();
			VERBOSE = (WTProperties.getLocalProperties()).getProperty("ext.generic.project.reports.verbose", false);
			codebalocation = wtProperties.getProperty("wt.codebase.location", "");
		} catch (Throwable throwable) {
			throw new ExceptionInInitializerError(throwable);
		}
	}

	/**
	 * 输出调试信息
	 */
	private static void outDebugInfo(String info) {
		if (VERBOSE)
			System.out.println(CLASSNAME + ">>>" + info);
	}

	public static void getTemplateLocation(HSSFSheet sheet, HashMap map) {
		HSSFRow row = sheet.getRow(1);

		int nSheetCol = row.getLastCellNum();
		Iterator keyIter = map.keySet().iterator();
		while (keyIter.hasNext()) {
			Object key = keyIter.next();
			Object tableValue = map.get(key);
			for (int z = 0; z < nSheetCol; z++) {
				String cellValue = getExcelCellContent(sheet, 1, z);
				if (key.equals(cellValue)) {
					if (VERBOSE) {
						System.out.println(">>>key>>>" + key + ">>>cellValue>>>" + cellValue);
					}
					if (!tableValue.equals(z)) {
						// keyIter.remove();
						map.put(key, z);
					}

					continue;
				}
			}
		}

	}

	public static String getExcelCellContent(HSSFSheet sheet, int nRow, int nCol) {
		if (sheet == null || nRow < 0 || nCol < 0)
			return "";
		try {
			HSSFRow row = sheet.getRow(nRow);
			if (row == null)
				return "";
			HSSFCell aCell = row.getCell(nCol);
			if (aCell == null)
				return "";
			String content = aCell.getStringCellValue();
			if (content != null)
				content = content.trim();
			if (content == null)
				content = "";
			return content;
		} catch (Exception e) {
			System.out.println("	getExcelCellContent : error, nRow = '" + nRow + "' , nCol = '" + nCol + "'");
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 四舍五入并保留小数两位
	 * 
	 * @param d
	 * @return
	 */
	public static Double roundHalfUp(double d) {
		return new BigDecimal(d).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 根据成品编号查询对应的项目
	 * 
	 * @param part
	 *            成品
	 * @return
	 */
	public static Project2 getProjectByPartNumber(WTPart part) {
		Project2 project = null;
		if (VERBOSE) {
			System.out.println("find project by " + part.getNumber().toLowerCase().trim());
		}
		try {
			QuerySpec queryspec = new QuerySpec(Project2.class);
			queryspec.appendWhere(new SearchCondition(Project2.class, Project2.NAME, SearchCondition.LIKE, part.getNumber().trim(),false));
			QueryResult queryresult = PersistenceHelper.manager.find(queryspec);
			while (queryresult.hasMoreElements()) {
				project = (Project2) queryresult.nextElement();
				if (VERBOSE) {
					System.out.println("find by project partNumber" + part.getNumber() + ">>>>>>>" + project);

				}
			}
		} catch (QueryException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (WTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return project;
	}

	/**
	 * 根据所输入的条件选择名称或者全名符合条件的用户
	 * 
	 * @param findString
	 *            查找的字符串
	 * @return Vector 用户列表
	 * @exception WTException
	 *                windchill基本的例外
	 **/
	public static Vector getUserList(String findString) throws WTException {
		if (findString == null)
			return null;
		if (findString.trim().length() == 0)
			findString = "*";
		Vector userList = new Vector();
		Enumeration userList1 = OrganizationServicesHelper.manager.findLikeUser("name", findString);
		while (userList1 != null && userList1.hasMoreElements()) {
			userList.add((WTUser) userList1.nextElement());
		}
		Enumeration userList2 = OrganizationServicesHelper.manager.findLikeUser("fullName", findString);
		while (userList2 != null && userList2.hasMoreElements()) {
			WTUser user = (WTUser) userList2.nextElement();
			if (!userList.contains(user))
				userList.add(user);
		}
		return userList;
	}

	/**
	 * 通过输入条件查询满足条件的用户
	 * 
	 * @param findStr
	 *            关键字
	 * @return 用户列表
	 * @throws WTException
	 * @throws RemoteException
	 * @throws IOException
	 * @throws Exception
	 */
	public Vector getUserListVector(String findStr) throws WTException, RemoteException, IOException, Exception {
		if (!RemoteMethodServer.ServerFlag) {
			String s4 = "getUserListVector";
			Class aclass[] = { String.class };
			Object aobj[] = { findStr };
			return (Vector) RemoteMethodServer.getDefault().invoke(s4, null, this, aclass, aobj);
		} else {
			Vector projectInfos = getUserList(findStr);
			return projectInfos;
		}
	}

	/**
	 * 通过里程碑获取父汇总活动所有子活动交付物的情况,用于jsp页面展示
	 * 
	 * @param activity
	 * @return
	 * @throws WTException
	 */
	public static ArrayList getPhaseReviewDocBean(PlanActivity activity) throws WTException {

		outDebugInfo(CLASSNAME + ".getPhaseReviewDocBean()");
		ArrayList list = new ArrayList();
		if (activity != null) {
			Plannable planable = activity.getParentPlannable();
			if (!(planable instanceof PlanActivity)) {
				// 非活动节点直接返回
				outDebugInfo("planable  is not instanceof PlanActivity, return null!");
				return list;
			}
			PlanActivity parentActivity = (PlanActivity) planable;
			if (parentActivity == null || !parentActivity.isSummary()) {
				outDebugInfo("parentActivity==null||!parentActivity.isSummary()");
				return list;
			}
			outDebugInfo(">>>activity>>>:" + activity.getName() + " parent is " + parentActivity.getName() + " is isSummary=" + parentActivity.isSummary());
			WTCollection collection = PlannableHelper.service.getAllChildren(parentActivity);
			Iterator iterator = collection.persistableIterator();
			while (iterator.hasNext()) {
				PlanActivity childActivity = (PlanActivity) iterator.next();

				outDebugInfo("find the child activity " + childActivity);

				Vector vecDeliv = new Vector();
				vecDeliv = getPlanActivityDeliverables(childActivity);

				if (vecDeliv.size() > 0) {

					String activityID = "" + childActivity.getLineNumber();// 活动ID

					String activityName = childActivity.getName();// 活动名称
					// 所有者
					String owner = childActivity.getOwnership().getOwner().getObject() == null ? "" : childActivity.getOwnership().getOwner().getDisplayName();

					// 完成百分比
					Double dpercentFinished = childActivity.getPercentWorkComplete();
					outDebugInfo("dpercentFinished>>>1>>" + dpercentFinished);
					dpercentFinished = dpercentFinished / 100;// 除以100
					dpercentFinished = ProjectReportUtil.roundHalfUp(dpercentFinished);// 四舍五入
					outDebugInfo("dpercentFinished>>>>2>>" + dpercentFinished);
					dpercentFinished = dpercentFinished * 100;// 乘以100
					String s1 = NumberFormattingUtils.removeZeroDecimal(dpercentFinished);

					String activityPercent = s1 + "%";// 活动完成百分比

					for (int k = 0; k < vecDeliv.size(); k++) {

						PhaseReviewDocBean prdBean = new PhaseReviewDocBean();

						PlanDeliverable deliverable = (PlanDeliverable) vecDeliv.get(k);

						String delivName = deliverable.getName();// 可交付结果名称

						String delivOwner = deliverable.getOwnership().getOwner().getFullName();// 可交付结果所有者

						// 交付物完成百分比
						Double needDelivPoint = deliverable.getPercentComplete();
						needDelivPoint = ProjectReportUtil.roundHalfUp(needDelivPoint);// 四舍五入
						String s2 = NumberFormattingUtils.removeZeroDecimal(needDelivPoint);

						String delivPercent = s2 + "%";// 可交付结果完成百分比

						// 可交付结果最后期限
						Timestamp deadTime = deliverable.getDeadline();

						String delivDeadTime = "";
						if (deadTime != null) {
							// format time:yyyy-MM-dd HH:mm:ss
							deadTime.setHours(deadTime.getHours() + 8);
							delivDeadTime = WTStandardDateFormat.format(deadTime, "yyyy年MM月dd日");
						}
						outDebugInfo("deadTimeStr>>>>" + delivDeadTime);

						Object obj = deliverable.getSubject().getObject();
						String actualDelivNumber = "";// 实际交付对象编号
						String actualDelivName = "";// 实际交付对象名称
						String actualDelivState = "";// 实际交付对象状态
						// 主题
						String subTitle = "";
						if (obj instanceof WTDocument) {

							WTDocument wtDoc = (WTDocument) obj;
							outDebugInfo("obj instanceof WTDocument:" + wtDoc.getDisplayIdentifier());
							// 输出名称和状态

							actualDelivNumber = wtDoc.getNumber();
							actualDelivName = wtDoc.getName();
							actualDelivState = wtDoc.getState().getState().getDisplay();
							outDebugInfo("objName>>>>" + actualDelivName + ">>>objState>>>" + actualDelivState);

						} else if (obj instanceof EPMDocument) {
							outDebugInfo("obj instanceof EPMDocument");
							EPMDocument epmDoc = (EPMDocument) obj;
							// 输出名称和状态
							actualDelivNumber = epmDoc.getNumber();
							actualDelivName = epmDoc.getName();
							actualDelivState = epmDoc.getState().getState().getDisplay();
							outDebugInfo("objName>>>>" + actualDelivName + ">>>objState>>>" + actualDelivState);

						} else if (obj instanceof WTPart) {
							outDebugInfo("obj instanceof WTPart");
							WTPart wtPart = (WTPart) obj;

							actualDelivNumber = wtPart.getNumber();
							actualDelivName = wtPart.getName();
							actualDelivState = wtPart.getState().getState().getDisplay();
							outDebugInfo("objName>>>>" + actualDelivName + ">>>objState>>>" + actualDelivState);
						}
						outDebugInfo("activityID:" + activityID + " activityName:" + activityName + " owner:" + owner + " activityPercent:" + activityPercent + " delivName:" + delivName + " delivOwner:" + delivOwner + " delivPercent:" + delivPercent
								+ " delivDeadTime:" + delivDeadTime + " actualDelivNumber:" + actualDelivNumber + " actualDelivName:" + actualDelivName + " actualDelivState:" + actualDelivState);

						prdBean.setActiID(activityID);
						prdBean.setActiName(activityName);
						prdBean.setOwnerName(owner);
						prdBean.setActiPercent(activityPercent);
						prdBean.setDelivName(delivName);
						prdBean.setDelivOwner(delivOwner);
						prdBean.setDelivPercent(delivPercent);
						prdBean.setDelivDeadTime(delivDeadTime);
						prdBean.setActualDelivNumber(actualDelivNumber);
						prdBean.setActualDelivName(actualDelivName);
						prdBean.setActualDelivState(actualDelivState);

						System.out.println("prdBean.owner:>>>" + prdBean.getOwnerName());
						System.out.println("prdBean.activityName:>>>" + prdBean.getActiName());

						list.add(prdBean);

					}
				}

			}
		}
		return list;
	}

	/**
	 * 通过里程碑获取父汇总活动所有子活动交付物的情况,用于Excel导出
	 * 
	 * @param hwb
	 *            HSSFWorkbook
	 * @param parentActivity
	 *            汇总活动节点
	 * @throws WTException
	 */
	public static void getPhaseReviewDocBeanWriteToExcel(HSSFWorkbook hwb, PlanActivity parentActivity) throws WTException {

		outDebugInfo(CLASSNAME + ".getPhaseReviewDocBeanWriteToExcel()");

		WTCollection collection = PlannableHelper.service.getAllChildren(parentActivity);
		Iterator iterator = collection.persistableIterator();
		HSSFSheet sheet = hwb.getSheetAt(0);
		HSSFRow row = null;
		HSSFCell cell = null;
		int i=1;
		while (iterator.hasNext()) {
			PlanActivity childActivity = (PlanActivity) iterator.next();

			outDebugInfo("find the child activity " + childActivity);

			Vector vecDeliv = new Vector();
			vecDeliv = getPlanActivityDeliverables(childActivity);

			if (vecDeliv.size() > 0) {

				String activityID = "" + childActivity.getLineNumber();// 活动ID

				String activityName = childActivity.getName();// 活动名称
				// 所有者
				String owner = childActivity.getOwnership().getOwner().getObject() == null ? "" : childActivity.getOwnership().getOwner().getDisplayName();

				// 完成百分比
				Double dpercentFinished = childActivity.getPercentWorkComplete();
				outDebugInfo("dpercentFinished>>>1>>" + dpercentFinished);
				dpercentFinished = dpercentFinished / 100;// 除以100
				dpercentFinished = ProjectReportUtil.roundHalfUp(dpercentFinished);// 四舍五入
				outDebugInfo("dpercentFinished>>>>2>>" + dpercentFinished);
				dpercentFinished = dpercentFinished * 100;// 乘以100
				String s1 = NumberFormattingUtils.removeZeroDecimal(dpercentFinished);

				String activityPercent = s1 + "%";// 活动完成百分比
				
				row = sheet.getRow(i);
				//活动ID
				cell = row.getCell(0);
				cell.setCellValue(activityID);
				
				//活动名称
				cell = row.getCell(1);
				cell.setCellValue(activityName);
				
				//活动所有着
				cell = row.getCell(2);
				cell.setCellValue(owner);
				
				//活动完成百分比
				cell = row.getCell(3);
				cell.setCellValue(activityPercent);
				
				for (int k = 0; k < vecDeliv.size(); k++) {

					PhaseReviewDocBean prdBean = new PhaseReviewDocBean();

					PlanDeliverable deliverable = (PlanDeliverable) vecDeliv.get(k);

					String delivName = deliverable.getName();// 可交付结果名称

					String delivOwner = deliverable.getOwnership().getOwner().getFullName();// 可交付结果所有者

					// 交付物完成百分比
					Double needDelivPoint = deliverable.getPercentComplete();
					needDelivPoint = ProjectReportUtil.roundHalfUp(needDelivPoint);// 四舍五入
					String s2 = NumberFormattingUtils.removeZeroDecimal(needDelivPoint);

					String delivPercent = s2 + "%";// 可交付结果完成百分比

					// 可交付结果最后期限
					Timestamp deadTime = deliverable.getDeadline();

					String delivDeadTime = "";
					if (deadTime != null) {
						// format time:yyyy-MM-dd HH:mm:ss
						deadTime.setHours(deadTime.getHours() + 8);
						delivDeadTime = WTStandardDateFormat.format(deadTime, "yyyy年MM月dd日");
					}
					outDebugInfo("deadTimeStr>>>>" + delivDeadTime);

					Object obj = deliverable.getSubject().getObject();
					String actualDelivNumber = "";// 实际交付对象编号
					String actualDelivName = "";// 实际交付对象名称
					String actualDelivState = "";// 实际交付对象状态
					// 主题
					String subTitle = "";
					if (obj instanceof WTDocument) {

						WTDocument wtDoc = (WTDocument) obj;
						outDebugInfo("obj instanceof WTDocument:" + wtDoc.getDisplayIdentifier());
						// 输出名称和状态

						actualDelivNumber = wtDoc.getNumber();
						actualDelivName = wtDoc.getName();
						actualDelivState = wtDoc.getState().getState().getDisplay();
						outDebugInfo("objName>>>>" + actualDelivName + ">>>objState>>>" + actualDelivState);

					} else if (obj instanceof EPMDocument) {
						outDebugInfo("obj instanceof EPMDocument");
						EPMDocument epmDoc = (EPMDocument) obj;
						// 输出名称和状态
						actualDelivNumber = epmDoc.getNumber();
						actualDelivName = epmDoc.getName();
						actualDelivState = epmDoc.getState().getState().getDisplay();
						outDebugInfo("objName>>>>" + actualDelivName + ">>>objState>>>" + actualDelivState);

					} else if (obj instanceof WTPart) {
						outDebugInfo("obj instanceof WTPart");
						WTPart wtPart = (WTPart) obj;

						actualDelivNumber = wtPart.getNumber();
						actualDelivName = wtPart.getName();
						actualDelivState = wtPart.getState().getState().getDisplay();
						outDebugInfo("objName>>>>" + actualDelivName + ">>>objState>>>" + actualDelivState);
					}
					outDebugInfo("activityID:" + activityID + " activityName:" + activityName + " owner:" + owner + " activityPercent:" + activityPercent + " delivName:" + delivName + " delivOwner:" + delivOwner + " delivPercent:" + delivPercent
							+ " delivDeadTime:" + delivDeadTime + " actualDelivNumber:" + actualDelivNumber + " actualDelivName:" + actualDelivName + " actualDelivState:" + actualDelivState);

					/*prdBean.setActiID(activityID);
					prdBean.setActiName(activityName);
					prdBean.setOwnerName(owner);
					prdBean.setActiPercent(activityPercent);
					prdBean.setDelivName(delivName);
					prdBean.setDelivOwner(delivOwner);
					prdBean.setDelivPercent(delivPercent);
					prdBean.setDelivDeadTime(delivDeadTime);
					prdBean.setActualDelivNumber(actualDelivNumber);
					prdBean.setActualDelivName(actualDelivName);
					prdBean.setActualDelivState(actualDelivState);

					System.out.println("prdBean.owner:>>>" + prdBean.getOwnerName());
					System.out.println("prdBean.activityName:>>>" + prdBean.getActiName());*/

					row = sheet.getRow(i);
					
					//可交付结果名称
					cell = row.getCell(4);
					cell.setCellValue(delivName);
					
					//可交付结果所有者
					cell = row.getCell(5);
					cell.setCellValue(delivOwner);
					
					//交付完成百分比
					cell = row.getCell(6);
					cell.setCellValue(delivPercent);
					
					//可交付结果最后期限
					cell = row.getCell(7);
					cell.setCellValue(delivDeadTime);
					
					//实际交付对象编号
					cell = row.getCell(8);
					cell.setCellValue(actualDelivNumber);
					
					//实际交付对象名称
					cell = row.getCell(9);
					cell.setCellValue(actualDelivName);
					
					//实际交付对象状态
					cell = row.getCell(10);
					cell.setCellValue(actualDelivState);
					i++;

				}

			}
		}
		

	}

	/**
	 * 获取活动的所有可交付结果
	 * 
	 * @param activity
	 *            活动
	 * @return 交付结果集合
	 * @throws WTException
	 */
	public static Vector getPlanActivityDeliverables(PlanActivity activity) throws WTException {
		Vector vecDeliv = new Vector();
		if (activity != null) {
			WTCollection wtc = PlannableHelper.service.getPlanDeliverableLinks(activity);
			if (wtc.size() > 0) {
				Iterator itor = wtc.iterator();
				int i = 0;
				while (itor.hasNext()) {
					Object objItor = itor.next();
					ObjectReference ref = (ObjectReference) objItor;
					PlanDeliverableLink pdl = (PlanDeliverableLink) ref.getObject();
					PlanDeliverable planDelive = pdl.getPlanDeliverable();
					outDebugInfo(i + " find  activity deliverable " + planDelive);
					vecDeliv.add(planDelive);
					i++;
				}
			}
		}
		return vecDeliv;
	}

}
